#ifndef AVALON_SERVICELOCATORDATASTORE_HPP
#define AVALON_SERVICELOCATORDATASTORE_HPP
#include <string>
#include "Avalon/IO/ClientConnection.hpp"
#include "Avalon/ServiceLocator/Directory.hpp"
#include "Avalon/ServiceLocator/DirectoryEntry.hpp"
#include "Avalon/ServiceLocator/ServiceLocator.hpp"

namespace Avalon {
namespace ServiceLocator {

  /*! \class ServiceLocatorDataStore
   *  \brief Base class used to store ServiceLocatorClient data.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  class ServiceLocatorDataStore : public IO::ClientConnection {
    public:

      virtual ~ServiceLocatorDataStore();

      //! Returns the total number of Accounts.
      virtual int LoadAccountCount() = 0;

      //! Loads a DirectoryEntry's Tag.
      /*!
        \param id The id of the Tag to load.
        \return The Tag with the specified <i>id</i>.
      */
      virtual DirectoryEntry::Tag LoadTag(unsigned int id) = 0;

      //! Loads a DirectoryEntry's parent's Tag.
      /*!
        \param id The id whose parent Tag is to be loaded.
        \return The Tag of <i>id</i>'s parent.
      */
      virtual DirectoryEntry::Tag LoadParentTag(unsigned int id) = 0;

      //! Loads a Account's Tag from it's name.
      /*!
        \param name The name of the Account.
        \return The Account Tag with the specified <i>name</i>.
      */
      virtual DirectoryEntry::Tag LoadAccountTag(const std::string& name) = 0;

      //! Creates a new Directory.
      /*!
        \param name The name of the Directory.
        \param directory The parent Directory.
        \return The id of the Directory created.
      */
      virtual unsigned int CreateDirectory(const std::string& name,
        const DirectoryEntry::Tag& directory) = 0;

      //! Deletes a Directory.
      /*!
        \param id The id of the Directory to delete.
      */
      virtual void DeleteDirectory(unsigned int id) = 0;

      //! Moves a DirectoryEntry to another Directory.
      /*!
        \param id The id of the DirectoryEntry to move.
        \param directory The id of the Directory to move the entry to.
      */
      virtual void MoveEntry(unsigned int id, unsigned int directory) = 0;

      //! Loads all of the DirectoryEntries within a Directory.
      /*!
        \param id The id of the Directory.
        \return The list of DirectoryEntries found within the Directory with
                specified <i>id</i>.
      */
      virtual std::vector<DirectoryEntry::Tag> LoadDirectoryEntries(
        unsigned int id) = 0;

      //! Creates a new Account.
      /*!
        \param name The name of the Account.
        \param directory The Account's Directory.
        \return The new Account id.
      */
      virtual unsigned int CreateAccount(const std::string& name,
        const DirectoryEntry::Tag& directory) = 0;

      //! Deletes an Account.
      /*!
        \param id The id of the Account to delete.
      */
      virtual void DeleteAccount(unsigned int id) = 0;

      //! Loads an Account's password.
      /*!
        \param account The Account id.
        \return The password associated with the <i>account</i>.
      */
      virtual std::string LoadPassword(unsigned int account) = 0;

      //! Sets an Account's password.
      /*!
        \param account The Account id.
        \param password The new password.
      */
      virtual void SetPassword(unsigned int account,
        const std::string& password) = 0;

      //! Loads a Directory's Permissions.
      /*!
        \param id The id of the Directory whose Permissions are to be loaded.
        \return The Permissions map for the specified Directory.
      */
      virtual std::map<unsigned int, Directory::Permission> LoadPermissions(
        unsigned int id) = 0;

      //! Loads an Account's Permissions for a Directory.
      /*!
        \param account The id of the Account.
        \param directory The id of the Directory.
        \return The <i>account</i>'s Permissions for the specified
                <i>directory</i>.
      */
      virtual Directory::Permission LoadAccountPermissions(unsigned int account,
        unsigned int directory) = 0;

      //! Sets an Account's Permissions for a Directory.
      /*!
        \param account The id of the Account.
        \param directory The id of the Directory.
        \param permissions The Permissions to grant to the <i>account</i> for
               the specified <i>directory</i>.
      */
      virtual void SetPermissions(unsigned int account, unsigned int directory,
        Directory::Permission permissions) = 0;

      //! Returns the list of unavailable names.
      virtual std::vector<std::string> GetUnavailableNames() = 0;

      //! Checks if a name is available.
      virtual bool IsNameAvailable(const std::string& name) = 0;

      //! Adds a name to the unavailable names list.
      /*!
        \param name The name to add.
      */
      virtual void AddUnavailableName(const std::string& name) = 0;

      //! Removes a name from the unavailable names list.
      /*!
        \param name The name to remove.
      */
      virtual void RemoveUnavailableName(const std::string& name) = 0;
  };
}
}

#endif // AVALON_SERVICELOCATORDATASTORE_HPP
